package buildConfigHandler;

import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang.StringUtils;

import util.FileUtil;
import util.LoadProperties;
import util.OSinfo;

import com.bcs.codgen.model.InOutType;
import com.bcs.codgen.model.OutputModel;
import com.bcs.codgen.model.TemplateModel;
import com.bcs.codgen.service.BuildConfig;
import com.bcs.codgen.service.BuildConfigHandler;
import com.bcs.codgen.service.impl.ProjectBuildConfig;
import com.bcs.codgen.util.BuilderHelper;
import com.bcs.codgen.util.ClassLoaderUtil;
import com.bcs.codgen.util.FilenameUtil;

public class FrameworkBuildConfigHandler implements BuildConfigHandler,Serializable {


	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public void initConfig(BuildConfig buildConfig) {
		
	}
	
	public void afterParseDataModel(BuildConfig buildConfig) {
		ProjectBuildConfig pbConfig = (ProjectBuildConfig)buildConfig;
		//获取输出文件夹
		String outDir = (String)pbConfig.getDataModel().get(ProjectBuildConfig.DMK_OUTPUTDIRECTORY);
		if(OSinfo.isWindows()){
			outDir = LoadProperties.getSystemdefaultValue(LoadProperties.KEY_OUTPUT_PATH, LoadProperties.FILE_OUTPUT_PROPERTIES)+outDir;
		}
		outDir = FilenameUtil.normalize(outDir+File.separatorChar);
		pbConfig.getDataModel().put(ProjectBuildConfig.DMK_OUTPUTDIRECTORY,outDir);
	}

	public void afterParseOutputModel(BuildConfig buildConfig) {
		ProjectBuildConfig pbConfig = (ProjectBuildConfig)buildConfig;
		//获取模板文件夹
		String tplDir = (String) pbConfig.getDataModel().get(ProjectBuildConfig.DMK_TEMPLATEDIRECTORY);
		tplDir = new File(ClassLoaderUtil.getResource(tplDir).getFile()).getAbsolutePath();
		tplDir = FilenameUtil.normalize(tplDir+File.separatorChar);

		//获取模板文件列表
		List<String> tplFileList = new ArrayList<String>();
		getAllFiles(new File(tplDir), tplFileList);
		
		//获取输出文件夹
		String outDir = (String)pbConfig.getDataModel().get(ProjectBuildConfig.DMK_OUTPUTDIRECTORY);

		//先清理输出文件夹，防止打包下载时包含历史文件
		File outDirFile = new File(outDir);
		if(outDirFile.exists()){
			FileUtil.deleteDirectory(outDirFile);
		}

		//先把模板文件夹拷贝到目标文件夹，然后再解析输出替换
		//FileUtil.copyFolder(tplDir, outDir);
		
		//根据模板文件结构组装同结构的输出文件列表
		TemplateModel templateModel;
		OutputModel outputModel;
		Map<String,OutputModel> outputModelMap = pbConfig.getOutputModel();
		Map<String,OutputModel> excludeOutputMap = new LinkedHashMap<String, OutputModel>();  
		for (String tplFile : tplFileList) {
			templateModel = new TemplateModel();
			templateModel.setName(tplFile);
			templateModel.setType(InOutType.FILE);
			templateModel.setTemplate(tplFile);			
			
			String outFile = outDir + StringUtils.removeStart(tplFile, tplDir);
			//解析带有构建参数的字符串
			outFile = BuilderHelper.parseBuildParams(pbConfig.getDataModel(), outFile);
			outputModel = new OutputModel(outFile);
			outputModel.setType(InOutType.FILE);
			outputModel.setOutput(outFile);
			outputModel.setTemplateModel(templateModel);
			if(includeFile(outputModel)==false){
				excludeOutputMap.put(outFile, outputModel);
			}else{
				outputModelMap.put(outFile, outputModel);
			}			
		}
		
		//不需要解析构建的文件直接复制
		for (Entry<String,OutputModel> entry: excludeOutputMap.entrySet()) {
			File file = new File(entry.getValue().getOutput());
			if(file.getParentFile().exists()==false){
				file.getParentFile().mkdirs();
			}
			String outputPath = entry.getValue().getOutput();
			//特殊文件处理
			if(outputPath.endsWith("gitignore")&& !outputPath.endsWith(".gitignore")){
				outputPath = outputPath.replace("gitignore",".gitignore");
			}
			FileUtil.copyFile(entry.getValue().getTemplateModel().getTemplate(), outputPath);
			System.out.println("复制原始文件="+entry.getValue().getOutput());
		}
	}

	public void beforeParseDataModel(BuildConfig buildConfig) {
		// TODO Auto-generated method stub
		
	}

	public void beforeParseOutputModel(BuildConfig buildConfig) {
		
	}
	
	private static void getAllFiles(File dir, List<String> fileList) {
		File[] fs = dir.listFiles();
		if(fs!=null&&fs.length>0){
			for(int i=0; i<fs.length; i++){
				/*if(includeFile(fs[i])==false){
					continue;
				}*/
				if(fs[i].isDirectory()){
					try{
						getAllFiles(fs[i],fileList);
					}catch(Exception e){}
				}else{
					fileList.add(fs[i].getAbsolutePath());
					System.out.println(fs[i].getAbsolutePath());
				}
			}
		}
	}

	/**
	 * 是否包含文件，返回true则包含，否则不包含
	 * @param outputModel
	 * @return
	 */
	private static boolean includeFile(OutputModel outputModel) {
		String[] excludeKeys=new String[]{".git","gitignore",".eot",".svg",".ttf",".woff",".jpg",".png",".js",".css"};
		for (String key : excludeKeys) {
			if(outputModel.getOutput().contains(key)){
				return false;
			}
		}
		
		return true;
	}	
}
